package com.inspur.edp.formserver.viewmodel.common;

import com.inspur.edp.bef.bizentity.GspBusinessEntity;
import com.inspur.edp.bef.bizentity.operation.BizOperation;
import com.inspur.edp.bef.bizentity.operation.Determination;
import com.inspur.edp.bef.component.detailcmpentity.vm.VMComponent;
import com.inspur.edp.bef.component.detailcmpentity.vm.VMMethodParameter;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.designtime.api.element.GspElementDataType;
import com.inspur.edp.cef.designtime.api.operation.CommonDetermination;
import com.inspur.edp.cef.designtime.api.util.MetadataUtil;
import com.inspur.edp.cef.designtime.api.variable.CommonVariable;
import com.inspur.edp.formserver.viewmodel.GspViewModel;
import com.inspur.edp.formserver.viewmodel.action.MappedCdpAction;
import com.inspur.edp.formserver.viewmodel.action.ViewModelAction;
import com.inspur.edp.formserver.viewmodel.action.ViewModelActionInfo;
import com.inspur.edp.formserver.viewmodel.action.ViewModelActionType;
import com.inspur.edp.formserver.viewmodel.action.mappedcdp.MappedCdpActionParameter;
import com.inspur.edp.formserver.viewmodel.exception.ViewModelException;
import com.inspur.edp.formserver.viewmodel.exception.VoModelErrorCodes;
import com.inspur.edp.formserver.viewmodel.i18n.VMI8nResourceUtil;
import com.inspur.edp.formserver.viewmodel.i18n.names.VoResourceKeyNames;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.entity.MetadataReference;

import java.util.Iterator;
import java.util.List;
import java.util.UUID;

public class ViewModelActionUtil {
    private static final String BEID = "beId";
    private static final String PROCESSCATEGORY = "processCategory";
    private static final String BIZCAtEGORY = "bizCategory";
    private static final String BEFORESAVE_COMPONENTID = "be7a44fd-9a73-4595-8f28-9137ecb399aa";
    private static final String VARDTM_COMPONENTID = "0315970a-488c-4454-8e64-c13cb3210c8c";
    private static final String SUMMARY = "summary";

    private static final String VOACTIONID = "811993be-7e11-4e0f-92d6-81c7669d586f";
    private static final String VARDETERMINATIONID = "e88fe87d-7855-40e2-b6bd-149618251d61";

    private static final String BEFORESAVE_DETERMINATION_ID = "6b3f4f6a-26f2-4199-8159-e36435c63245";
    private static final String DELETE_DETERMINATION_ID = "0e7d3731-049b-49b9-9e46-2046ef957843";

    public final static void addVoActions(GspViewModel vm, String beId, String processCategory, String bizCategory, String summary) {
        addDataExtendInfo(vm, beId, processCategory, bizCategory, summary);
    }

    public final static void removeActions(GspViewModel vm, GspBusinessEntity be, boolean enableDraft) {
        if (enableDraft)
            return;

        if (vm.getDataExtendInfo().getBeforeSaveActions() != null && vm.getDataExtendInfo().getBeforeSaveActions().size() != 0) {
            Iterator<ViewModelAction> iterators = vm.getDataExtendInfo().getBeforeSaveActions().iterator();
            while (iterators.hasNext()) {
                MappedCdpAction mappedCdpAction = (MappedCdpAction) iterators.next();
                if (VOACTIONID.equals(mappedCdpAction.getID())) {
                    iterators.remove();
                    break;
                }

            }
        }

        if (be.getMainObject().getDeterminations() != null && be.getMainObject().getDeterminations().size() != 0) {
            Iterator<BizOperation> iterators = be.getMainObject().getDeterminations().iterator();
            while (iterators.hasNext()) {
                Determination mappedCdpAction = (Determination) iterators.next();
                if (BEFORESAVE_DETERMINATION_ID.equals(mappedCdpAction.getID())) {
                    iterators.remove();
                    break;
                }
            }
        }

        if (be.getMainObject().getDeterminations() != null && be.getMainObject().getDeterminations().size() != 0) {
            Iterator<BizOperation> iterators = be.getMainObject().getDeterminations().iterator();
            while (iterators.hasNext()) {
                Determination mappedCdpAction = (Determination) iterators.next();
                if (DELETE_DETERMINATION_ID.equals(mappedCdpAction.getID())) {
                    iterators.remove();
                    break;
                }
            }
        }
    }

    public static MappedCdpAction getMappedCdpAction(String componentID) {
        MappedCdpAction action = new MappedCdpAction();
        action.setID(VOACTIONID);
        String code = "InitDraftVar";
        action.setCode(code);
        action.setType(ViewModelActionType.VMAction);
        action.setName(code);
        action.setComponentEntityId(componentID);
        action.setComponentName("DraftVarBeforeSave");
        return action;
    }

    /**
     * @param vm
     * @param beId
     * @param processCategory
     * @param bizCategory
     * @param summary
     */
    public static void addDataExtendInfo(GspViewModel vm, String beId, String processCategory, String bizCategory, String summary) {
        boolean isExistedAction = isExistedVoAction(vm, VOACTIONID);
        //是否已经添加
        if (isExistedAction)
            return;
        MappedCdpAction action = getMappedCdpAction(BEFORESAVE_COMPONENTID);

        GspMetadata metadata = MetadataUtil.getCustomMetadata(BEFORESAVE_COMPONENTID);
        if (metadata == null) {
            throw new ViewModelException(VoModelErrorCodes.GSP_VIEWOBJECT_MODEL_1026, null, BEFORESAVE_COMPONENTID);
        }
        VMComponent vmComponent = (VMComponent) metadata.getContent();
        VMMethodParameter beIdPar = null;
        VMMethodParameter processCategoryPar = null;
        VMMethodParameter bizCategoryPar = null;
        VMMethodParameter summaryPar = null;
        for (VMMethodParameter param : vmComponent.getVmMethod().getParams()) {
            if (param.getParamCode().equalsIgnoreCase(BEID)) {
                beIdPar = param;
            } else if (param.getParamCode().equalsIgnoreCase(PROCESSCATEGORY)) {
                processCategoryPar = param;
            } else if (param.getParamCode().equalsIgnoreCase(BIZCAtEGORY)) {
                bizCategoryPar = param;
            } else if (param.getParamCode().equalsIgnoreCase(SUMMARY)) {
                summaryPar = param;
            }
        }
        MappedCdpActionParameter parBeId = getMappedCdpActionParameter(beIdPar, beId);
        action.getParameterCollection().add(parBeId);

        MappedCdpActionParameter parProcessCategory = getMappedCdpActionParameter(processCategoryPar, processCategory);
        action.getParameterCollection().add(parProcessCategory);

        MappedCdpActionParameter parBizCategory = getMappedCdpActionParameter(bizCategoryPar, bizCategory);
        action.getParameterCollection().add(parBizCategory);

        MappedCdpActionParameter parSummary = getMappedCdpActionParameter(summaryPar, summary);
        action.getParameterCollection().add(parSummary);
        vm.getDataExtendInfo().getBeforeSaveActions().add(action);
    }

    private static boolean isExistedVoAction(GspViewModel vm, String actionId) {
        boolean isExist = false;
        if (vm.getDataExtendInfo().getBeforeSaveActions() == null || vm.getDataExtendInfo().getBeforeSaveActions().size() == 0)
            isExist = false;
        for (ViewModelAction action : vm.getDataExtendInfo().getBeforeSaveActions()) {
            if (actionId.equals(action.getID())) {
                isExist = true;
                break;
            }
        }
        return isExist;
    }

    public static MappedCdpActionParameter getMappedCdpActionParameter(VMMethodParameter beIdPar, String value) {
        MappedCdpActionParameter parameter = new MappedCdpActionParameter();
        parameter.setID(beIdPar.getID());
        parameter.setParamName(beIdPar.getParamName());
        parameter.setParamCode(beIdPar.getParamCode());
        parameter.setParameterType(VMParameterType.String);
        parameter.getActualValue().setHasValue(true);
        parameter.getActualValue().setEnable(true);
        parameter.getActualValue().setValue(value);
        return parameter;
    }

    private static CommonVariable getCommonVariable(String varCode) {
        CommonVariable variable = new CommonVariable();
        variable.setID(UUID.randomUUID().toString());
        variable.setCode(varCode);
        variable.setName(varCode);
        variable.setMDataType(GspElementDataType.String);
        variable.setLabelID(varCode);
        variable.setLength(36);
        variable.setEnableRtrim(true);
        return variable;
    }

    /**
     * @param vm
     */
    public static void addVariables(GspViewModel vm) {

        addVariable(vm, "bffTaskDraftBeId");
        addVariable(vm, "bffTaskDraftProcessCategory");
        addVariable(vm, "bffTaskDraftBizCategory");
        addVariable(vm, "bffTaskDraftSummary");

    }

    public static void addVariable(GspViewModel vm, String varCode) {
        boolean isExistedVar = isExistedVariable(vm, varCode);
        if (isExistedVar)
            return;
        CommonVariable var = getCommonVariable(varCode);
        vm.getVariables().getContainElements().addField(var);
    }

    private static boolean isExistedVariable(GspViewModel vm, String varCode) {
        boolean isExistedVariable = false;
        if (vm.getVariables().getContainElements() == null || vm.getVariables().getContainElements().size() == 0)
            isExistedVariable = false;
        for (IGspCommonField variable : vm.getVariables().getContainElements()) {
            if (varCode.equals(variable.getCode())) {
                isExistedVariable = true;
                break;
            }
        }
        return isExistedVariable;
    }

    public static CommonDetermination getCommonOperation(String code, String name, String componentName, String componentId) {
        CommonDetermination determination = new CommonDetermination();
        determination.setID(VARDETERMINATIONID);
        determination.setCode(code);
        determination.setName(name);
        determination.setComponentName(componentName);
        determination.setComponentId(componentId);
        return determination;
    }

    /**
     * @param vm
     */
    public static void addVarDeterminations(GspViewModel vm) {
        boolean isExistedVarDtm = isExistedVarDtm(vm, VARDETERMINATIONID);
        if (isExistedVarDtm)
            return;
        CommonDetermination determination = getCommonOperation("DraftVariableDtm", "DraftVariableDtm", "DraftVarDeterminationAction", VARDTM_COMPONENTID);
        vm.getVariables().getDtmAfterModify().add(determination);

    }

    private static boolean isExistedVarDtm(GspViewModel vm, String actionId) {
        boolean isExist = false;
        if (vm.getVariables().getDtmAfterModify() == null || vm.getVariables().getDtmAfterModify().size() == 0)
            isExist = false;
        for (CommonDetermination action : vm.getVariables().getDtmAfterModify()) {
            if (actionId.equals(action.getID())) {
                isExist = true;
                break;
            }
        }
        return isExist;
    }

    public static ViewModelActionInfo getActionInfo(MappedCdpAction action, GspViewModel viewModel, GspMetadata metadata) {
        ViewModelActionInfo actionInfo = new ViewModelActionInfo();
        actionInfo.setViewModel(viewModel);
        actionInfo.setCode(action.getCode());
        actionInfo.setName(action.getName());
        actionInfo.setCompId(action.getComponentEntityId());
        actionInfo.setCompName(action.getComponentName());
        actionInfo.setSourceMeta(metadata);
        return actionInfo;
    }

    public static ViewModelActionInfo getActionInfo(CommonDetermination determination, GspViewModel viewModel, GspMetadata metadata) {
        ViewModelActionInfo actionInfo = new ViewModelActionInfo();
        actionInfo.setViewModel(viewModel);
        actionInfo.setCode(determination.getCode());
        actionInfo.setName(determination.getName());
        actionInfo.setCompId(determination.getComponentId());
        actionInfo.setCompName(determination.getComponentName());
        actionInfo.setSourceMeta(metadata);
        return actionInfo;
    }

    @Deprecated
    public static String getViewModelMessage(GspViewModel viewModel, GspMetadata sourceMeta) {
        if (sourceMeta == null || sourceMeta.getHeader() == null) {
            return VMI8nResourceUtil.getMessage(VoResourceKeyNames.VIEWMODEL_MESSAGE_PREFIX_0,
                    viewModel.getCode(), viewModel.getName());
        }
        return VMI8nResourceUtil.getMessage(VoResourceKeyNames.VIEWMODEL_MESSAGE_PREFIX_1,
                viewModel.getCode(), viewModel.getName(), sourceMeta.getHeader().getNameSpace());
    }

    @Deprecated
    public static String getExceptionMessage(GspMetadata metadata, String id, StringBuilder builder) {
        if (metadata == null || metadata.getRefs() == null || metadata.getRefs().size() == 0) {
            return builder.toString();
        }
        MetadataReference ref = getReference(metadata.getRefs(), id);
        if (ref == null || ref.getDependentMetadata() == null) {
            return builder.toString();
        }
        builder.append(VMI8nResourceUtil.getMessage(VoResourceKeyNames.VIEWMODEL_MESSAGE_PREFIX_2,
                ref.getDependentMetadata().getCode(),
                ref.getDependentMetadata().getName(),
                ref.getDependentMetadata().getNameSpace()));
        return builder.toString();
    }

    public static MetadataReference getReference(List<MetadataReference> refs, String id) {
        for (MetadataReference ref : refs) {
            if (id.equals(ref.getDependentMetadata().getId())) {
                return ref;
            }
        }
        return null;
    }
}
